<?php


namespace models\Business;


use models\Exception\Business\AccountException;
use models\Exception\Business\MemberException;
use models\Exception\DAO\ModelDriverException;
use models\Exception\DAO\ModelException;
use models\Exception\DAO\ModelReflectionException;
use models\Exception\DAO\ModelSqlException;
use models\Exception\Service\ServiceException;
use models\Exception\Transformer\TransformerException;
use models\Service\AccountService;
use models\Service\MemberService;
use Yaf\Registry;
use youliPhpLib\Common\StringOperation;

class Account
{
    /**
     * @param array $modules
     * @return array
     */
    static public function getAccountsByModules($modules = []) {
        $account = $account_info_arr = null;
        try {

            $account_id_arr = array_filter(array_column($modules['data'], 'account_id'));

            if (count($account_id_arr) == 1)
                $account['data'][] = AccountService::getInstance()->getOne(implode(',', $account_id_arr));
            else
                $account = AccountService::getInstance()->getList(1, count($account_id_arr), 'desc', 'id',
                    ['groupOp' => 'AND', 'rules' => [
                        ['field' => 'id', 'op' => 'in', 'data' => implode(',', $account_id_arr)]]]);

            foreach ($account['data'] as $account_info) {
                $account_info_arr[$account_info['id']] = $account_info['account'] . '-' . $account_info['name'] . '-' . $account_info['mobile'];
            }
        } catch (\Exception $e) {

        } finally {
            foreach ($modules['data'] as $idx => $module_info) {
                $modules['data'][$idx]['account_info'] = isset($account_info_arr[$module_info['account_id']]) ?
                    $account_info_arr[$module_info['account_id']] : '';
            }

            return $modules;
        }
    }

    /**
     * 获取提现账号列表
     * @param array $parameters
     * @return array|mixed
     * @throws AccountException
     * @throws MemberException
     * @throws ModelDriverException
     * @throws ModelReflectionException
     * @throws ModelSqlException
     * @throws ServiceException
     * @throws TransformerException
     */
    static public function getAccountList($parameters = []) {
        try {
            $rules = $condition = [];
            if (! isset($parameters['from_api']) || $parameters['from_api'] !== true) {

                $member_id_arr = [];
                if (isset($parameters['mobile'])) {
                    $member = MemberService::getInstance()->getList(1, 999, 'desc', 'id', ['groupOp' => 'AND', 'rules' => [
                        ['field' => 'mobile', 'op' => 'nc', 'data' => $parameters['mobile'] . '%']]]);
                    if (! empty($member['data']))
                        $member_id_arr = array_column($member['data'], 'id');
                    else
                        throw new MemberException(MemberException::MEMBER_IS_NOT_EXISTS, MemberException::MEMBER_IS_NOT_EXISTS_NO);
                }

                if (isset($parameters['nickname'])) {
                    $member = MemberService::getInstance()->getList(1, 999, 'desc', 'id', ['groupOp' => 'AND', 'rules' => [
                        ['field' => 'nickname', 'op' => 'nc', 'data' => $parameters['nickname'] . '%']]]);
                    if (! empty($member['data']))
                        $member_id_arr = empty($member_id_arr) ? array_column($member['data'], 'id') :
                            array_merge($member_id_arr, array_column($member['data'], 'id'));
                    else
                        throw new MemberException(MemberException::MEMBER_IS_NOT_EXISTS, MemberException::MEMBER_IS_NOT_EXISTS_NO);
                }

                if (!empty($member_id_arr))
                    array_push($rules, ['field' => 'member_id', 'op' => 'in', 'data' => implode(',', $member_id_arr)]);
            } else
                array_push($rules, ['field' => 'member_id', 'op' => 'eq', 'data' => Registry::get('jwt_info')->id]);

            if (isset($parameters['stats']))
                array_push($rules, ['field' => 'stats', 'op' => 'eq', 'data' => $parameters['stats']]);

            if (isset($parameters['type']))
                array_push($rules, ['field' => 'type', 'op' => 'eq', 'data' => $parameters['type']]);

            if (isset($parameters['account']))
                array_push($rules, ['field' => 'account', 'op' => 'nc', 'data' => $parameters['account'] . '%']);

            if (isset($parameters['name']))
                array_push($rules, ['field' => 'name', 'op' => 'nc', 'data' => $parameters['name'] . '%']);

            if (isset($parameters['withdraw_mobile']))
                array_push($rules, ['field' => 'mobile', 'op' => 'nc', 'data' => $parameters['withdraw_mobile'] . '%']);

            if (isset($parameters['start_created_at']))
                array_push($rules, ['field' => 'created_at', 'op' => 'ge', 'data' => date("Y-m-d 00:00:00", strtotime(str_replace('/', '-', $parameters['start_created_at'])))]);

            if (isset($parameters['end_created_at']))
                array_push($rules, ['field' => 'created_at', 'op' => 'le', 'data' => date("Y-m-d 23:59:59", strtotime(str_replace('/', '-', $parameters['end_created_at'])))]);

            if (!empty($rules))
                $condition = ['groupOp' => 'AND', 'rules' => $rules];

            $accounts = AccountService::getInstance()->getList(
                isset($parameters['page']) ? $parameters['page'] : 1,
                isset($parameters['page_size']) ? $parameters['page_size'] : 10,
                isset($parameters['sort']) ? $parameters['sort'] : 'desc',
                isset($parameters['order']) ? $parameters['order'] : 'id',
                $condition
            );

            $accounts = Member::getMembersByModules($accounts, false);

            return $accounts;
        } catch (ModelDriverException $e) {
            throw $e;
        } catch (ModelException $e) {
            if ($e->getCode() == ModelException::DATA_NOT_EXISTS_NO)
                throw new AccountException(AccountException::ACCOUNT_IS_NOT_EXISTS, AccountException::ACCOUNT_IS_NOT_EXISTS_NO);
        } catch (ModelReflectionException $e) {
            throw $e;
        } catch (ModelSqlException $e) {
            throw $e;
        } catch (ServiceException $e) {
            throw $e;
        } catch (TransformerException $e) {
            throw $e;
        }
    }

    /**
     * @param array $parameters
     * @throws AccountException
     * @throws ModelDriverException
     * @throws ModelException
     * @throws ModelReflectionException
     * @throws ModelSqlException
     * @throws ServiceException
     * @throws TransformerException
     */
    static public function deleteAccount($parameters = []) {
        try {
            if (! isset($parameters['id']) || empty($parameters['id']))
                throw new AccountException(AccountException::ACCOUNT_ID_IS_EMPTY, AccountException::ACCOUNT_ID_IS_EMPTY_NO);


            if (isset($parameters['from_api']) && $parameters['from_api'] === true) {
                try {
                    $account = AccountService::getInstance()->getOne($parameters['id']);

                    if ($account['member_id'] != Registry::get('jwt_info')->id)
                        throw new AccountException(AccountException::ACCOUNT_DENIED, AccountException::ACCOUNT_DENIED_NO);
                } catch (AccountException $e) {
                    throw $e;
                } catch (ModelException $e) {
                    if ($e->getCode() == ModelException::DATA_NOT_EXISTS_NO)
                        throw new AccountException(AccountException::ACCOUNT_IS_NOT_EXISTS, AccountException::ACCOUNT_IS_NOT_EXISTS_NO);
                }
            }

            AccountService::getInstance()->delete($parameters['id']);
        } catch (ModelDriverException $e) {
            if ($e->getCode() == ModelDriverException::DRIVER_EXCEPTION_MSG_NO)
                throw new AccountException(AccountException::ACCOUNT_DELETE_FAILURE, AccountException::ACCOUNT_DELETE_FAILURE_NO);
            throw $e;
        } catch (ModelException $e) {
            throw $e;
        } catch (ModelReflectionException $e) {
            throw $e;
        } catch (ModelSqlException $e) {
            throw $e;
        } catch (ServiceException $e) {
            throw $e;
        }
    }

    /**
     * @param array $parameters
     * @return array|mixed|null
     * @throws AccountException
     * @throws ModelDriverException
     * @throws ModelException
     * @throws ModelReflectionException
     * @throws ModelSqlException
     * @throws ServiceException
     * @throws TransformerException
     */
    static public function editAccount($parameters = []) {
        try {
            if (! isset($parameters['id']) || empty($parameters['id']))
                throw new AccountException(AccountException::ACCOUNT_ID_IS_EMPTY, AccountException::ACCOUNT_ID_IS_EMPTY_NO);

            $account = [];
            if (isset($parameters['from_api']) && $parameters['from_api'] === true) {
                try {
                    $account = AccountService::getInstance()->getOne($parameters['id']);

                    if ($account['member_id'] != Registry::get('jwt_info')->id)
                        throw new AccountException(AccountException::ACCOUNT_DENIED, AccountException::ACCOUNT_DENIED_NO);
                } catch (AccountException $e) {
                    throw $e;
                } catch (ModelException $e) {
                    if ($e->getCode() == ModelException::DATA_NOT_EXISTS_NO)
                        throw new AccountException(AccountException::ACCOUNT_IS_NOT_EXISTS, AccountException::ACCOUNT_IS_NOT_EXISTS_NO);
                }
            }

            $update_arr = [];
            if (isset($parameters['type'])) {
                $account_type_is_exists = [];
                // 检查是否创建过指定渠道的账号
                try {
                    $account_type_is_exists = AccountService::getInstance()->getOne(['groupOp' => 'AND', 'rules' => [
                        ['field' => 'id', 'op' => 'ne', 'data' => $parameters['id']],
                        ['field' => 'type', 'op' => 'eq', 'data' => $parameters['type']],
                        ['field' => 'member_id', 'op' => 'eq', 'data' => Registry::get('jwt_info')->id],
                    ]]);
                } catch (\Exception $e) {

                }

                if ($account_type_is_exists) {
                    $msg = str_replace('#channel#', ($parameters['type'] == 2 ? '银行卡' : ($parameters['type'] == 1 ? '微信' : '支付宝')), AccountException::ACCOUNT_IS_EXISTS);
                    throw new AccountException($msg, AccountException::ACCOUNT_IS_EXISTS_NO);
                }

                $update_arr['type'] = $parameters['type'];
            }

            if (isset($parameters['name']))
                $update_arr['name'] = $parameters['name'];

            if (isset($parameters['mobile']))
                $update_arr['mobile'] = $parameters['mobile'];

            if (isset($parameters['account']))
                $update_arr['account'] = $parameters['account'];

            if (isset($parameters['stats']))
                $update_arr['stats'] = $parameters['stats'];

            if (!empty($update_arr))
                $account = AccountService::getInstance()->update($update_arr, $parameters['id']);

            else if (! $account)
                $account = AccountService::getInstance()->getOne($parameters['id']);

            return $account;
        } catch (AccountException $e) {
            throw $e;
        } catch (ModelDriverException $e) {
            if ($e->getCode() == ModelDriverException::DRIVER_EXCEPTION_MSG_NO)
                throw new AccountException(AccountException::ACCOUNT_EDIT_FAILURE, AccountException::ACCOUNT_EDIT_FAILURE_NO);
            throw $e;
        } catch (ModelException $e) {
            throw $e;
        } catch (ModelReflectionException $e) {
            throw $e;
        } catch (ModelSqlException $e) {
            throw $e;
        } catch (ServiceException $e) {
            throw $e;
        } catch (TransformerException $e) {
            throw $e;
        }
    }

    /**
     * 创建提现账号
     * @param array $parameters
     * @return array
     * @throws AccountException
     * @throws MemberException
     * @throws ModelDriverException
     * @throws ModelException
     * @throws ModelReflectionException
     * @throws ModelSqlException
     * @throws TransformerException
     */
    static public function createAccount($parameters = []) {
        // 判断手机号码是否有效
        try {
            StringOperation::mobileIsValid($parameters['mobile']);
        } catch (\Exception $e) {
            throw new MemberException(MemberException::INVALID_MOBILE_EMPTY, MemberException::INVALID_MOBILE_EMPTY_NO);
        }

        // 检查是否创建过指定渠道的账号
        $account_type_is_exists = [];
        try {
            $account_type_is_exists = AccountService::getInstance()->getOne(['groupOp' => 'AND', 'rules' => [
                ['field' => 'type', 'op' => 'eq', 'data' => $parameters['type']],
                ['field' => 'member_id', 'op' => 'eq', 'data' => Registry::get('jwt_info')->id]
            ]]);
        } catch (\Exception $e) {

        }

        if ($account_type_is_exists) {
            $msg = str_replace('#channel#', ($parameters['type'] == 2 ? '银行卡' : ($parameters['type'] == 1 ? '微信' : '支付宝')), AccountException::ACCOUNT_IS_EXISTS);
            throw new AccountException($msg, AccountException::ACCOUNT_IS_EXISTS_NO);
        }

        try {

            $extend_arr = [];
            if (isset($parameters['identify']) && !empty($parameters['identify']))
                $extend_arr['identify'] = $parameters['identify'];

            // $type = 0, $member_id = 0, $name = "",
            // $account = "", $mobile = "", $stats = 0, $extend_field = ""
            return AccountService::getInstance()->create(
                $parameters['type'], Registry::get('jwt_info')->id, $parameters['name'],
                $parameters['account'], $parameters['mobile'], 1, json_encode($extend_arr)
            );
        } catch (AccountException $e) {
            throw $e;
        } catch (ModelDriverException $e) {
            if ($e->getCode() == ModelDriverException::DRIVER_EXCEPTION_MSG_NO)
                throw new AccountException(AccountException::ACCOUNT_CREATE_FAILURE, AccountException::ACCOUNT_CREATE_FAILURE_NO);
            throw $e;
        } catch (ModelException $e) {
            throw $e;
        } catch (ModelReflectionException $e) {
            throw $e;
        } catch (ModelSqlException $e) {
            throw $e;
        } catch (TransformerException $e) {
            throw $e;
        } catch (ServiceException $e) {
            throw new AccountException(AccountException::ACCOUNT_CREATE_FAILURE, AccountException::ACCOUNT_CREATE_FAILURE_NO);
        }
    }

}
